package simpledb.execution;

import simpledb.optimizer.LogicalJoinNode;

import java.util.*;

/**
 * PlanCache 是一个辅助类，用于缓存给定一组连接（join）集合的最优连接顺序。
 * 它记录了：
 * - 每组连接的最优执行顺序（plan）
 * - 执行该计划的成本（cost）
 * - 执行结果的基数（cardinality）
 *
 * 主要用于查询优化器中动态规划算法的中间结果存储，避免重复计算。
 */
public class PlanCache {

    // 缓存每组连接集合的最佳连接顺序
    final Map<Set<LogicalJoinNode>, List<LogicalJoinNode>> bestOrders        = new HashMap<>();

    // 缓存每组连接集合的最佳执行成本
    final Map<Set<LogicalJoinNode>, Double>                bestCosts         = new HashMap<>();

    // 缓存每组连接集合的执行结果基数（即输出行数）
    final Map<Set<LogicalJoinNode>, Integer>               bestCardinalities = new HashMap<>();

    /**
     * 添加一个新的连接计划到缓存中，包括成本、基数和连接顺序。
     * 注意：不会验证新添加的成本是否比之前的小，只是简单地添加或替换已有计划。
     *
     * @param s 要缓存的连接集合（set of joins）
     * @param cost 该计划的预估执行成本
     * @param card 该计划的预估输出行数（基数）
     * @param order 连接顺序（List形式）
     */
    public void addPlan(Set<LogicalJoinNode> s, double cost, int card, List<LogicalJoinNode> order) {
        bestOrders.put(s, order);
        bestCosts.put(s, cost);
        bestCardinalities.put(s, card);
    }

    /**
     * 获取指定连接集合的最优连接顺序
     *
     * @param s 要查找的连接集合
     * @return 该连接集合的最优连接顺序（List形式），若不存在则返回 null
     */
    public List<LogicalJoinNode> getOrder(Set<LogicalJoinNode> s) {
        return bestOrders.get(s);
    }

    /**
     * 获取指定连接集合的最优连接计划的预估成本
     *
     * @param s 要查找的连接集合
     * @return 该连接集合的最优计划成本，若不存在则返回 null
     */
    public double getCost(Set<LogicalJoinNode> s) {
        return bestCosts.get(s);
    }

    /**
     * 获取指定连接集合的最优连接计划的预估输出行数（基数）
     *
     * @param s 要查找的连接集合
     * @return 该连接集合的最优计划的输出行数，若不存在则返回 null
     */
    public int getCard(Set<LogicalJoinNode> s) {
        return bestCardinalities.get(s);
    }
}
